<?php
/**
 * Amazon MWS class
 *
 * Help to format output and errors.
 *
 */
class Amazon_mws {


	public $output = array();
	public $error  = array();
	public $next_token = '';
	public $filename = '';
	private $CI;
	private $xw;
	function __construct()
	{
		$this->CI = & get_instance();

		$this->CI->load->model('inventory_model');
		$this->CI->load->model('merchant_model');
		$this->CI->load->library('form_validation');
	}


	function format_output( $response = null, $response_index = '', $ouput_index = '' )
	{
		$array_index = explode('|', $response_index);

		$dom = new DOMDocument();
		$dom->loadXML($response->toXML());
		$dom->preserveWhiteSpace = false;
		$dom->formatOutput = true;
		$elm_count  = $dom->getElementsByTagName(end($array_index))->length;

		$xml = $dom->saveXML();
		//die($xml);

		$result = json_decode(json_encode((array)simplexml_load_string($xml)), true);

		//echo '<pre>';print_r($result);die;


		foreach($array_index as $k => $val)
		{
			if( array_key_exists($val, $result) )
			{
				$result = $result[$val];
			}
		}

		$formatted_result = array();

		if($elm_count === 1)
		{
			$formatted_result[] = $result;
		}
		else
		{
			$formatted_result = & $result;
		}

		if( !array_key_exists($ouput_index, $this->output))
		$this->output[$ouput_index] = array();


		$this->output[$ouput_index] = array_merge($this->output[$ouput_index],$formatted_result);
	}


	function format_error( $xml = '' )
	{

		$result = json_decode(json_encode((array)simplexml_load_string($xml)), true);

		$this->error['ErrorResponse'] = $result;
	}

	function show_ouput($flag = TRUE)
	{
		if( $flag )
		{
			if( $this->next_token != '' )
			$this->output['next_token'] = $this->next_token;
			if( $this->filename != '' )
			$this->output['filePath'] = base_url(ltrim($this->filename, '.'));

			$this->CI->response($this->output, 200);
		}
		else
		{
			$this->CI->response($this->error, 200);
		}

	}

	function set_request( $params = array(), $type = 'get')
	{
		foreach ($params as $key => $val)
		{
			$tmp = trim($this->CI->input->$type($key));

			if( strcmp('',$tmp) === 0 )
			continue;

			switch ($val['type'])
			{
				case 'date':
					$tmp = gmdate('Y-m-d\TH:i:s\Z', strtotime($tmp));
					break;
				case 'array':
					$tmp = explode('|', $tmp);
					break;
				case 'boolean':
					$tmp = $tmp;
					break;
				case 'class':
					$tmp = explode('|', $tmp);

					include_once(APPPATH.'libraries/MarketplaceWebServiceProducts/Model/'.$key.'Type.php');

					$class_name = 'MarketplaceWebServiceProducts_Model_'.$key.'Type';
					$set_method = 'set'.str_replace('List','',$key);

					$list = new $class_name();
					$list->$set_method($tmp); //20 sku's only allowed
					$tmp = $list;
					break;
				case 'FeedSubmissionIdList':
					include_once(APPPATH.'libraries/MarketplaceWebService/Model/IdList.php');
					$idl = explode('|', $tmp);
					$tmp = new MarketplaceWebService_Model_IdList();
					call_user_func_array(array($tmp, "withId"), $idl);

					break;
				case 'ReportRequestIdList':
					include_once(APPPATH.'libraries/MarketplaceWebService/Model/IdList.php');
					$idl = explode('|', $tmp);
					$tmp = new MarketplaceWebService_Model_IdList();
					call_user_func_array(array($tmp, "withId"), $idl);
						

					break;
				case 'ReportTypeList':
					include_once(APPPATH.'libraries/MarketplaceWebService/Model/TypeList.php');
					$rtl = $tmp;
					$tmp = new MarketplaceWebService_Model_TypeList();
					$tmp->setType($rtl);
					break;
				case 'ReportProcessingStatusList':
					include_once(APPPATH.'libraries/MarketplaceWebService/Model/StatusList.php');
					$rtl = explode('|', $tmp);
					$tmp = new MarketplaceWebService_Model_StatusList();
					call_user_func_array(array($tmp, "withStatus"), $rtl);
						
					break;
				case 'FeedProcessingStatusList':
					include_once(APPPATH.'libraries/MarketplaceWebService/Model/StatusList.php');
					$rtl = explode('|', $tmp);
					$tmp = new MarketplaceWebService_Model_StatusList();
					call_user_func_array(array($tmp, "withStatus"), $rtl);
					
					break;		
				default:
					$tmp = $tmp;
				break;
			}

			$var_params = 'set'.$key;
			$this->CI->request->$var_params($tmp);

		}
	}


	function create_product_feed($merchant_id = '')
	{


		//get merchant details
		$merchant_details = $this->CI->merchant_model->get_by_merchant_id( $merchant_id );

		if( !count($merchant_details) )
		return FALSE;

		$where = array('MerchantID' => $merchant_id);
		$products =$this->CI->inventory_model->get_products($where);
		//echo '<pre>';print_r($products);die;

		if( !count($products) )
		return FALSE;

		$file_name = $this->create_file('feeds', 'product', 'xml');

		$this->xw = new XMLWriter();
		$this->xw->openURI($file_name);

		$this->xw->startDocument('1.0','UTF-8');
		$this->xw->startElement("AmazonEnvelope");
		$this->xw->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
		$this->xw->writeAttribute("xsi:noNamespaceSchemaLocation", "amzn-envelope.xsd");
			
		//header
		$this->xw->startElement("Header");
		$this->add_elm("DocumentVersion", '1.01');
		$this->add_elm("MerchantIdentifier", $merchant_details['merchant_token_id']);
		$this->xw->endElement();


		//message type
		$this->add_elm("MessageType", 'Product');

		foreach ($products as $key => $row)
		{
			$this->xw->startElement("Message");
				
				$this->add_elm("MessageID", $key+1);
				$this->add_elm("OperationType", 'Update');
					
				//product start
				$this->xw->startElement("Product");
					
					$this->add_elm('SKU', $row['SKU'], 'trim|required');
					//StandardProductID
					if( $this->validate($row['StandardProductID_Type'], 'trim|required') )
					{
						$this->xw->startElement('StandardProductID');
						$this->add_elm('Type', $row['StandardProductID_Type']);
						$this->add_elm('Value', $row['StandardProductID_Value']);
						$this->xw->endElement();
					}
					$this->add_elm('ProductTaxCode', $row['ProductTaxCode'], 'trim|required');
					$launch_date = gmdate('Y-m-d\TH:i:s\Z', strtotime($row['LaunchDate']));
					$release_date = gmdate('Y-m-d\TH:i:s\Z', strtotime($row['ReleaseDate']));
					$this->add_elm('LaunchDate', $launch_date, 'trim|required');
					$this->add_elm('ReleaseDate', $release_date, 'trim|required');
					$this->add_elm('Condition', $row['Condition'], 'trim|required');
					$this->add_elm('ItemPackageQuantity', $row['ItemPackageQuantity'], 'trim|required');
					$this->add_elm('NumberOfItems', $row['NumberOfItems'], 'trim|required');
		
					$this->xw->startElement("DescriptionData");
		
						$this->add_elm('Title', $row['Title'], 'trim|required');
						$this->add_elm('Brand', $row['Brand'], 'trim|required');
						$this->add_elm('Manufacturer', $row['Manufacturer'], 'trim|required');
						$this->add_elm('MfrPartNumber', $row['MfrPartNumber'], 'trim|required');
						$this->add_elm('ItemType', $row['ItemType'], 'trim|required');
						$this->add_elm('Designer', $row['Designer'], 'trim|required');
						$this->add_elm('Description', $row['Description'], 'trim|required');
							
						//Bulletpoints
						for($i=1;$i<=5;$i++)
						{
							if( $this->validate($row['BulletPoint_'.$i], 'trim|required') )
							$this->add_elm('BulletPoint', $row['BulletPoint_'.$i] );
						}
							
						$this->xw->startElement('ItemDimensions');
							$attr = array('unitOfMeasure' => $row['ItemDimensions_UOM']);
							$this->add_elm('Length', $row['ItemDimensions_Length'], 'trim|required|numeric|greater_than[0]', $attr);
							$this->add_elm('Width', $row['ItemDimensions_Width'], 'trim|required|numeric|greater_than[0]', $attr);
							$this->add_elm('Height', $row['ItemDimensions_Height'], 'trim|required|numeric|greater_than[0]', $attr);
						$this->xw->endElement();
							
						$this->xw->startElement('PackageDimensions');
							$attr = array('unitOfMeasure' => $row['PackageDimensions_UOM']);
							$this->add_elm('Length', $row['PackageDimensions_Length'], 'trim|required|numeric|greater_than[0]', $attr);
							$this->add_elm('Width', $row['PackageDimensions_Width'], 'trim|required|numeric|greater_than[0]', $attr);
							$this->add_elm('Height', $row['PackageDimensions_Height'], 'trim|required|numeric|greater_than[0]', $attr);
						$this->xw->endElement();
							
						$attr = array('unitOfMeasure' =>$row['PackageWeight_UOM']);
						$this->add_elm('PackageWeight', $row['PackageWeight_Value'], 'trim|required|numeric|greater_than[0]', $attr);
							
						$attr = array('unitOfMeasure' =>$row['ShippingWeight_UOM']);
						$this->add_elm('ShippingWeight', $row['ShippingWeight_Value'], 'trim|required|numeric|greater_than[0]', $attr);
							
						$this->add_elm('MerchantCatalogNumber', $row['MerchantCatalogNumber'], 'trim|required');
							
						$attr = array('currency' =>'USD');
						$this->add_elm('MSRP', $row['MSRP'], 'trim|required|numeric|greater_than[0]', $attr);
						$this->add_elm('MaxOrderQuantity', $row['MaxOrderQuantity'], 'trim|required|greater_than[0]');
						$this->add_elm('SerialNumberRequired', $row['SerialNumberRequired'], 'trim|required');
						$this->add_elm('Prop65', $row['Prop65'], 'trim|required');
						$this->add_elm('LegalDisclaimer', $row['LegalDisclaimer'], 'trim|required');
						$this->add_elm('Prop65', $row['Prop65'], 'trim|required');
						$this->add_elm('Memorabilia', $row['Memorabilia'], 'trim|required');
						$this->add_elm('Autographed', $row['Autographed'], 'trim|required');
						$this->add_elm('TargetAudience', $row['TargetAudience'], 'trim|required');
						$this->add_elm('IsGiftWrapAvailable', $row['IsGiftWrapAvailable'], 'trim|required');
						$this->add_elm('IsGiftMessageAvailable', $row['IsGiftMessageAvailable'], 'trim|required');
						$this->add_elm('IsDiscontinuedByManufacturer', $row['IsDiscontinuedByManufacturer'], 'trim|required');
						$this->add_elm('MaxAggregateShipQuantity', $row['MaxAggregateShipQuantity'], 'trim|required');
							
						//search terms
						for($i=1;$i<=5;$i++)
						{
							if( $this->validate($row['SearchTerms_'.$i], 'trim|required') )
								$this->add_elm('SearchTerms', $row['SearchTerms_'.$i] );
						}
						
						//PlatinumKeywords
						for($i=1;$i<=5;$i++)
						{
							if( $this->validate($row['PlatinumKeywords_'.$i], 'trim|required') )
								$this->add_elm('PlatinumKeywords', $row['PlatinumKeywords_'.$i] );
						}
						
						//UsedFor
						for($i=1;$i<=5;$i++)
						{
							if( $this->validate($row['UsedFor_'.$i], 'trim|required') )
								$this->add_elm('UsedFor', $row['UsedFor_'.$i] );
						}
						
					$this->xw->endElement();	
	
	
				//product end
				$this->xw->endElement();
				
			//message end
			$this->xw->endElement();
				
		}


		//end-envelope
		$this->xw->endElement();
		$this->xw->endDocument();
		$this->xw->flush();
		
		return $file_name;
	}


	function create_inventory_feed( $merchant_id = '')
	{
		//get merchant details
		$merchant_details = $this->CI->merchant_model->get_by_merchant_id( $merchant_id );

		if( !count($merchant_details) )
		return FALSE;

		$where = array('MerchantID' => $merchant_id);
		$inventory =$this->CI->inventory_model->get_product_inventory($where);
		//echo '<pre>';print_r($products);die;

		if( !count($inventory) )
		return FALSE;

		$file_name = $this->create_file('feeds', 'inventory', 'xml');

		$this->xw = new XMLWriter();
		$this->xw->openURI($file_name);

		$this->xw->startDocument('1.0','UTF-8');
		$this->xw->startElement("AmazonEnvelope");
		$this->xw->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
		$this->xw->writeAttribute("xsi:noNamespaceSchemaLocation", "amzn-envelope.xsd");
			
		//header
		$this->xw->startElement("Header");
		$this->add_elm("DocumentVersion", '1.01');
		$this->add_elm("MerchantIdentifier", $merchant_details['merchant_token_id']);
		$this->xw->endElement();


		//message type
		$this->add_elm("MessageType", 'Inventory');

		foreach ($inventory as $key => $row)
		{
			//message start
			$this->xw->startElement("Message");

			$this->add_elm("MessageID", $key+1);
			$this->add_elm("OperationType", 'Update');

			//Inventory start
			$this->xw->startElement("Inventory");
			$this->add_elm("SKU", $row['SKU']);
			$this->add_elm("Quantity", $row['Quantity']);
			$this->add_elm("Available", $row['Available']);
			$this->add_elm("FulfillmentCenterID", $row['FulfillmentCenterID']);
			if( $row['FulfillmentCenterID'] == 'AFN')
			{
				$this->add_elm("Lookup", 'FulfillmentNetwork');
			}
			if( $row['SwitchFulfillmentTo'] != '' )
				$this->add_elm("SwitchFulfillmentTo", $row['SwitchFulfillmentTo']);
				
			//Inventory end
			$this->xw->endElement();

			//message end
			$this->xw->endElement();
		}


		//end-envelope
		$this->xw->endElement();
		$this->xw->endDocument();
		$this->xw->flush();

		return $file_name;

	}



	function create_price_feed($merchant_id = '')
	{
		//get merchant details
		$merchant_details = $this->CI->merchant_model->get_by_merchant_id( $merchant_id );

		if( !count($merchant_details) )
		return FALSE;

		$where = array('MerchantID' => $merchant_id);
		$prices =$this->CI->inventory_model->get_product_prices($where);
		//echo '<pre>';print_r($products);die;

		if( !count($prices) )
		return FALSE;

		$file_name = $this->create_file('feeds', 'price', 'xml');

		$this->xw = new XMLWriter();
		$this->xw->openURI($file_name);

		$this->xw->startDocument('1.0','UTF-8');
		$this->xw->startElement("AmazonEnvelope");
		$this->xw->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
		$this->xw->writeAttribute("xsi:noNamespaceSchemaLocation", "amzn-envelope.xsd");
			
		//header
		$this->xw->startElement("Header");
		$this->add_elm("DocumentVersion", '1.01');
		$this->add_elm("MerchantIdentifier", $merchant_details['merchant_token_id']);
		$this->xw->endElement();


		//message type
		$this->add_elm("MessageType", 'Price');

		foreach ($prices as $key => $row)
		{
			//message start
			$this->xw->startElement("Message");
				
			$this->add_elm("MessageID", $key+1);
			$this->add_elm("OperationType", 'Update');
				
			//price start
			$this->xw->startElement("Price");
			$this->add_elm("SKU", $row['SKU']);
			$this->add_elm("StandardPrice", $row['StandardPrice'], 'trim|required|greater_than[0]', array('currency'=>'USD'));
			$this->add_elm("MAP", $row['MAP'], 'trim|required|greater_than[0]', array('currency'=>'USD'));
			
			if( $this->validate($row['Sale_SalePrice'],'trim|required|greater_than[0]'))
			{
				$this->xw->startElement("Sale");
					$this->add_elm("SalePrice", $row['Sale_SalePrice'], 'trim|required|greater_than[0]', array('currency'=>'USD'));
					if( $row['Sale_StartDate'] != '' && $row['Sale_StartDate'] != '0000-00-00 00:00:00')
					{
						$start_date = gmdate('Y-m-d\TH:i:s\Z', strtotime($row['Sale_StartDate']));
						$this->add_elm("StartDate", $start_date, '');
					
					}
					if( $row['Sale_StartDate'] != '' && $row['Sale_StartDate'] != '0000-00-00 00:00:00')
					{
						$end_date = gmdate('Y-m-d\TH:i:s\Z', strtotime($row['Sale_EndDate']));
						$this->add_elm("EndDate", $end_date, '');
							
					}
				$this->xw->endElement();
			}
			
			//price end
			$this->xw->endElement();

			//message end
			$this->xw->endElement();
		}


		//end-envelope
		$this->xw->endElement();
		$this->xw->endDocument();
		$this->xw->flush();


		return $file_name;
	}


	function create_image_feed($merchant_id = '')
	{
		//get merchant details
		$merchant_details = $this->CI->merchant_model->get_by_merchant_id( $merchant_id );

		if( !count($merchant_details) )
		return FALSE;

		$where = array('MerchantID' => $merchant_id);
		$images =$this->CI->inventory_model->get_product_images($where);
		//echo '<pre>';print_r($products);die;

		if( !count($images) )
		return FALSE;

		$file_name = $this->create_file('feeds', 'image', 'xml');

		$this->xw = new XMLWriter();
		$this->xw->openURI($file_name);

		$this->xw->startDocument('1.0','UTF-8');
		$this->xw->startElement("AmazonEnvelope");
		$this->xw->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
		$this->xw->writeAttribute("xsi:noNamespaceSchemaLocation", "amzn-envelope.xsd");
			
		//header
		$this->xw->startElement("Header");
		$this->add_elm("DocumentVersion", '1.01');
		$this->add_elm("MerchantIdentifier", $merchant_details['merchant_token_id']);
		$this->xw->endElement();


		//message type
		$this->add_elm("MessageType", 'ProductImage');

		foreach ($images as $key => $row)
		{
			$records = array();

			if( $this->CI->form_validation->required( $row['Main'] ) )
			$records[] = array('type' => 'Main', 'path' => $row['Main']);
				
			if( $this->CI->form_validation->required( $row['Alternate_1'] ) )
			$records[] = array('type' => 'PT1', 'path' => $row['Alternate_1']);
				
			if( $this->CI->form_validation->required( $row['Alternate_2'] ) )
			$records[] = array('type' => 'PT2', 'path' => $row['Alternate_2']);
				
			if( $this->CI->form_validation->required( $row['Alternate_3'] ) )
			$records[] = array('type' => 'PT3', 'path' => $row['Alternate_3']);
				
			if( $this->CI->form_validation->required( $row['Alternate_4'] ) )
			$records[] = array('type' => 'PT4', 'path' => $row['Alternate_4']);
				
			if( $this->CI->form_validation->required( $row['Alternate_5'] ) )
			$records[] = array('type' => 'PT5', 'path' => $row['Alternate_5']);
				
			if( $this->CI->form_validation->required( $row['Swatch'] ) )
			$records[] = array('type' => 'Swatch', 'path' => $row['Swatch']);
				
			foreach ($records as $record)
			{
				//message start
				$this->xw->startElement("Message");

				$this->add_elm("MessageID", $key+1);
				$this->add_elm("OperationType", 'Update');

				$this->xw->startElement("ProductImage");
				$this->add_elm("SKU", $row['SKU']);
				$this->add_elm("ImageType", $record['type']);
				$this->add_elm("ImageLocation", $record['path']);
				$this->xw->endElement();
					
				//message end
				$this->xw->endElement();
			}
		}


		//end-envelope
		$this->xw->endElement();
		$this->xw->endDocument();
		$this->xw->flush();

		return $file_name;

	}

	private function add_elm( $name = null, $value = null, $rules = '', $attrs = array())
	{
		if( is_null($name) || is_null($value) )
		return FALSE;

		if( !$this->validate($value, $rules) )
		return FALSE;

		$this->xw->startElement($name);
		foreach( $attrs as $k=>$v)
		$this->xw->writeAttribute($k, $v);

		$this->xw->text($value);
		$this->xw->endElement();

	}

	private function validate($str = '', $rules = 'trim|required')
	{
		$_POST['str'] = $str;

		$this->CI->form_validation->set_rules('str', '', $rules);

		if( !$this->CI->form_validation->run() )
		return FALSE;

		return TRUE;;
	}

	/**
	 * create_feed_file
	 * @param string $path <p>
	 * The path in which this function is going to create new unique file name.
	 * </p>
	 * @return string.returns the created filename.
	 */

	function create_file($type = 'reports', $id = null, $file_format='txt')
	{

		switch ($type) {
			case 'feeds':
				$path = './assets/feeds/';
				break;
			case 'reports':
				$path = './assets/reports/';
				break;
			default:
				$path = './assets/reports/';
			break;
		}
		static $inc = 0;

		$filename = $path.$type;

		if( !is_null($id) )
		$filename .= '-'.$id;

		$filename .= '-'.date('YmdTHis');

		if($inc)
		$filename .= '-'.$inc;

		$filename .= '.'.$file_format;


		//die("{$path}{$filename}");
		if (file_exists($filename))
		{
			$inc++;
			return $this->create_file($type, $id);
		}
		else
		{
			@fopen($filename, 'w+');
			@chmod($filename, 0777);
				
			$this->filename = $filename;
				
			return $this->filename;
		}
		
 }
 
 
 function convert_to_csv($fname = '', $from = 'tab')
 {
 	$result = array();
 	$fp = fopen($fname,'r');
 	if (($headers = fgetcsv($fp, 0, "\t")) !== FALSE)
 	{
 		if ($headers)
 		{
 			$result[] = $headers;
 			
 			while (($line = fgetcsv($fp, 0, "\t")) !== FALSE)
 			{
 				if ($line)
 				{
 					$result[] = $line;
 					/*if (sizeof($line)==sizeof($headers))
 					{
 						$result[] = array_combine($headers,$line);
 					}*/
 					
 				}
 			}
 		}
 	} 	
 	fclose($fp);
 	
 	if( count($result) )
 	{
 		$this->CI->load->helper('csv');
 		return array_to_csv($result);
 	}
 	
 	//echo '<pre>';print_r($result);die;
 }


}

/* End of file layout.php */
